#ifndef __step_h__
#define __step_h__

#include <functional>
#include <iostream>
#include <string>
#include <unordered_map>

#include "interface.h"

// 1. 初始化步骤
enum InitStepStatus {
  INIT_CHECK_HARDWARE,  // 0
  INIT_LOAD_CONFIG,     // 1
  INIT_VALIDATE_PARAM,  // 2
  INIT_RETRY,           // 3
  INIT_COMPLETE,        // 4
  INIT_FAILED           // 5
};

class InitStep : public Step {
 public:
  InitStep(IWorkflowNotify *notify)
      : Step("初始化", notify, INIT_CHECK_HARDWARE) {
    initStatusHandlers();
  }

 protected:
  std::string statusToString(unsigned int status) const override {
    switch (status) {
      case INIT_CHECK_HARDWARE:
        return "硬件检查";
      case INIT_LOAD_CONFIG:
        return "加载配置";
      case INIT_VALIDATE_PARAM:
        return "参数验证";
      case INIT_RETRY:
        return "初始化重试";
      case INIT_COMPLETE:
        return "完成";
      case INIT_FAILED:
        return "失败";
      default:
        return "未知";
    }
  }

  bool isCompleteStatus(unsigned int status) const override {
    return status == INIT_COMPLETE;
  }

  unsigned int getFailedStatus() const override { return INIT_FAILED; }

 private:
  int retry_count_ = 0;

  void initStatusHandlers() {
    status_handlers_[INIT_CHECK_HARDWARE] =
        std::bind(&InitStep::checkHardware, this, std::placeholders::_1,
                  std::placeholders::_2);
    status_handlers_[INIT_LOAD_CONFIG] =
        std::bind(&InitStep::loadConfig, this, std::placeholders::_1,
                  std::placeholders::_2);
    status_handlers_[INIT_VALIDATE_PARAM] =
        std::bind(&InitStep::validateParam, this, std::placeholders::_1,
                  std::placeholders::_2);
    status_handlers_[INIT_RETRY] = std::bind(
        &InitStep::retry, this, std::placeholders::_1, std::placeholders::_2);
  }

  bool checkHardware(unsigned int &next_status, int &progress);

  bool loadConfig(unsigned int &next_status, int &progress);

  bool validateParam(unsigned int &next_status, int &progress);

  bool retry(unsigned int &next_status, int &progress);
};

// 2. 数据采集步骤
enum DataCollectionStatus {
  COLLECT_PREPARE,        // 0
  COLLECT_SAMPLE,         // 1
  COLLECT_VERIFY,         // 2
  COLLECT_RETRY_PREPARE,  // 3
  COLLECT_RETRY_SAMPLE,   // 4
  COLLECT_COMPLETE,       // 5
  COLLECT_FAILED          // 6
};

class DataCollectionStep : public Step {
 public:
  DataCollectionStep(IWorkflowNotify *notify, IDataCollectionSupport *support,
                     int total_samples)
      : Step("数据采集", notify, COLLECT_PREPARE),
        support_(support),
        total_samples_(total_samples) {
    if (!support) {
      throw std::invalid_argument("Data collection support cannot be null");
    }
    if (total_samples <= 0) {
      throw std::invalid_argument("Total samples must be positive");
    }
    initStatusHandlers();
  }

 protected:
  std::string statusToString(unsigned int status) const override {
    switch (status) {
      case COLLECT_PREPARE:
        return "采集准备";
      case COLLECT_SAMPLE:
        return "采集样本";
      case COLLECT_VERIFY:
        return "数据验证";
      case COLLECT_RETRY_PREPARE:
        return "准备重试";
      case COLLECT_RETRY_SAMPLE:
        return "采集重试";
      case COLLECT_COMPLETE:
        return "完成";
      case COLLECT_FAILED:
        return "失败";
      default:
        return "未知";
    }
  }

  bool isCompleteStatus(unsigned int status) const override {
    return status == COLLECT_COMPLETE;
  }

  unsigned int getFailedStatus() const override { return COLLECT_FAILED; }

 private:
  IDataCollectionSupport *support_;
  int total_samples_;
  int collected_samples_ = 0;
  int prepare_retry_ = 0;
  int collect_retry_ = 0;

  void initStatusHandlers() {
    status_handlers_[COLLECT_PREPARE] =
        std::bind(&DataCollectionStep::prepareCollect, this,
                  std::placeholders::_1, std::placeholders::_2);
    status_handlers_[COLLECT_SAMPLE] =
        std::bind(&DataCollectionStep::collectSample, this,
                  std::placeholders::_1, std::placeholders::_2);
    status_handlers_[COLLECT_VERIFY] =
        std::bind(&DataCollectionStep::verifyData, this, std::placeholders::_1,
                  std::placeholders::_2);
    status_handlers_[COLLECT_RETRY_PREPARE] =
        std::bind(&DataCollectionStep::retryPrepare, this,
                  std::placeholders::_1, std::placeholders::_2);
    status_handlers_[COLLECT_RETRY_SAMPLE] =
        std::bind(&DataCollectionStep::retryCollect, this,
                  std::placeholders::_1, std::placeholders::_2);
  }

  bool prepareCollect(unsigned int &next_status, int &progress);

  bool collectSample(unsigned int &next_status, int &progress);

  bool verifyData(unsigned int &next_status, int &progress);

  bool retryPrepare(unsigned int &next_status, int &progress);

  bool retryCollect(unsigned int &next_status, int &progress);
};

#endif